home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
vbcc.lha
/
vbcc
/
regs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-30
|
43KB
|
1,081 lines
/* $VER: vbcc (regs.c) V0.4 */
/* Registerzuteilung */
#include "opt.h"
static char FILE_[]=__FILE__;
#ifndef NO_OPTIMIZER
int (*savings)[MAXR+1],regu[MAXR+1];
int *rvlist;
struct regp {int treg;struct Var *tvar,*tmp;};
void do_load_parms(struct regp [],struct flowgraph *);
void load_one_parm(int,int,struct Var *,struct Var *,struct flowgraph *);
int cmp_savings(const void *v1,const void *v2)
/* Vergleichsfkt, um rvlist nach savings zu sortieren */
{
return savings[*(int *)v2][0]-savings[*(int *)v1][0];
}
int entry_load(struct flowgraph *fg,int i)
/* Testet, ob die Variable in Register i am Anfang von Block fg geladen */
/* werden muss, d.h. ein Vorgaenger sie nicht im selben Register hat. */
{
struct flowlist *lp;
lp=fg->in;
while(lp){
if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]&&BTST(lp->graph->av_out,fg->regv[i]->index)) return(1);
lp=lp->next;
}
return(0);
}
int exit_save(struct flowgraph *fg,int i)
/* Testet, ob die Variable in Register i am Ende von Block fg gespeichert */
/* werden muss, d.h. der Vorgaenger eines Nachfolgers nicht dieselbe */
/* Variable im selben Register hat. */
{
struct flowlist *lp;
if((fg->normalout&&(!fg->end||fg->end->code!=BRA))&&BTST(fg->normalout->av_in,fg->regv[i]->index)){
if(fg->normalout->regv[i]!=fg->regv[i]) return(1);
lp=fg->normalout->in;
while(lp){
if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
lp=lp->next;
}
}
if(fg->branchout&&BTST(fg->branchout->av_in,fg->regv[i]->index)){
if(fg->branchout->regv[i]!=fg->regv[i]) return(1);
lp=fg->branchout->in;
while(lp){
if(lp->graph&&lp->graph->regv[i]!=fg->regv[i]) return(1);
lp=lp->next;
}
}
return(0);
}
void load_reg_parms(struct flowgraph *fg)
/* Laedt Registerparameter, falls noetig. */
{
int i,j; struct Var *v;
struct regp regp[MAXR+1]={0};
/* for(i=1;i<=MAXR;i++){ regp[i].treg=0;regp[i].tvar=0;} */
for(i=0;i<vcount-rcount;i++){
v=vilist[i];
if((v->flags®PARM)&&fg->regv[v->reg]!=v&&(BTST(fg->av_in,i)||(v->flags&USEDASADR))){
regp[v->reg].tvar=v;
for(j=1;j<=MAXR;j++)
if(fg->regv[j]==v) regp[v->reg].treg=j;
}
}
do_load_parms(regp,fg);
}
void insert_regs(struct flowgraph *fg1)
/* Fuegt Registervariablen in die ICs ein. */
{
int i;struct IC *p,*lic=0,*new;struct flowgraph *lfg=0,*fg;
if(DEBUG&9216) printf("inserting register variables\n");
fg=fg1;
while(fg){
if(DEBUG&8192) printf("block %d:\n",fg->index);
p=fg->start;
while(p){
for(i=1;i<=MAXR;i++){
if(!fg->regv[i]) continue;
if(p->code==ALLOCREG&&p->q1.reg==i) ierror(0);
if((p->q1.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q1.v==fg->regv[i]){
p->q1.flags|=REG;
p->q1.reg=i;
}
if((p->q2.flags&(VAR|DONTREGISTERIZE))==VAR&&p->q2.v==fg->regv[i]){
p->q2.flags|=REG;
p->q2.reg=i;
}
if((p->z.flags&(VAR|DONTREGISTERIZE))==VAR&&p->z.v==fg->regv[i]){
p->z.flags|=REG;
p->z.reg=i;
}
}
if(DEBUG&8192) pric2(stdout,p);
if(p==fg->end) break;
p=p->next;
}
if(fg->start&&fg->start->code==LABEL) lic=fg->start;
for(i=1;i<=MAXR;i++){
if(fg->regv[i]){
if(DEBUG&8192){
printf("(%s),%ld assigned to %s\n",fg->regv[i]->identifier,zl2l(fg->regv[i]->offset),regnames[i]);
if(BTST(fg->av_in,fg->regv[i]->index)) printf("active at the start of block\n");
if(BTST(fg->av_out,fg->regv[i]->index)) printf("active at the end of block\n");
}
if(BTST(fg->av_out,fg->regv[i]->index)){
/* Variable beim Austritt aktiv? */
if(exit_save(fg,i)){
struct IC *tp;
if(DEBUG&8192) printf("\thave to save it at end of block\n");
new=mymalloc(ICS);
new->line=0;
new->file=0;
new->code=ASSIGN;
new->typf=fg->regv[i]->vtyp->flags;
/* cc */
if(new->typf==0) ierror(0);
new->q1.flags=VAR|REG;
new->q1.val.vlong=l2zl(0L);
new->q1.v=fg->regv[i];
new->q1.reg=i;
new->q2.flags=0;
new->q2.val.vlong=szof(fg->regv[i]->vtyp);
new->z.flags=VAR|DONTREGISTERIZE;
new->z.val.vlong=l2zl(0L);
new->z.v=fg->regv[i];
new->q1.am=new->q2.am=new->z.am=0;
new->use_cnt=new->change_cnt=0;
new->use_list=new->change_list=0;
/* Vor FREEREGs und evtl. Branch+COMPARE/TEST setzen */
if(fg->end){
tp=fg->end;
while(tp!=fg->start&&tp->code==FREEREG)
tp=tp->prev;
if(tp&&tp->code>=BEQ&&tp->code<=BRA){
if(tp->code<BRA){
int c;
do{
tp=tp->prev;
c=tp->code;
if(c!=FREEREG&&c!=COMPARE&&c!=TEST) ierror(0);
}while(c!=COMPARE&&c!=TEST);
}
tp=tp->prev;
}
}else tp=lic;
insert_IC_fg(fg,tp,new);
}
}
if(BTST(fg->av_in,fg->regv[i]->index)){
if((fg==fg1||entry_load(fg,i))&&(fg!=fg1||!(fg->regv[i]->flags®PARM))){
if(DEBUG&8192) printf("\thave to load it at start of block\n");
new=mymalloc(ICS);
new->line=0;
new->file=0;
new->code=ASSIGN;
new->typf=fg->regv[i]->vtyp->flags;
/* cc */
if(new->typf==0) ierror(0);
new->q1.flags=VAR|DONTREGISTERIZE;
new->q1.val.vlong=l2zl(0L);
new->q1.v=fg->regv[i];
new->q2.flags=0;
new->q2.val.vlong=szof(fg->regv[i]->vtyp);
new->z.flags=VAR|REG;
new->z.val.vlong=l2zl(0L);
new->z.v=fg->regv[i];
new->z.reg=i;
new->q1.am=new->q2.am=new->z.am=0;
new->use_cnt=new->change_cnt=0;
new->use_list=new->change_list=0;
insert_IC_fg(fg,lic,new);
}
}
if(!lfg||!lfg->regv[i]) insert_allocreg(fg,lic,ALLOCREG,i);
if(!fg->normalout||!fg->normalout->regv[i])
insert_allocreg(fg,fg->end?fg->end:lic,FREEREG,i);
}
}
if(fg->end) lic=fg->end;
lfg=fg;
fg=fg->normalout;
}
load_reg_parms(fg1);
}
void do_loop_regs(struct flowgraph *start,struct flowgraph *end)
/* Macht die Variablenzuweisung in Schleife start-end. */
/* Wenn end==0 Registerzuweisung fuer die ganze Funktion, ansonsten */
/* fuer die Schleife, die zum Header start gehoert. */
{
struct flowgraph *g;
int i,r;
struct Var *lregs[MAXR+1]={0};
unsigne